home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / kerberos / pc / krb_libk.lha / Lib / KRB / KUSEROK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-19  |  5.7 KB  |  204 lines

  1. /*
  2.  * $Source: /mit/kerberos/src/lib/krb/RCS/kuserok.c,v $
  3.  * $Author: jtkohl $
  4.  *
  5.  * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
  6.  *
  7.  * For copying and distribution information, please see the file
  8.  * <mit-copyright.h>.
  9.  *
  10.  * kuserok: check if a kerberos principal has
  11.  * access to a local account
  12.  */
  13.  
  14. #if 0   /* DOES NOT WORK IN MSDOS -- Peter Tan */
  15.  
  16. #ifndef    lint
  17. static char rcsid_kuserok_c[] =
  18. "$Header: kuserok.c,v 4.5 89/01/23 09:25:21 jtkohl Exp $";
  19. #endif    lint
  20.  
  21. #include <mit_copy.h>
  22.  
  23. #include <krb.h>
  24. #include <stdio.h>
  25. #include <pwd.h>
  26. #include <sys/param.h>
  27. #include <sys/socket.h>
  28. #include <sys/stat.h>
  29. #include <sys/file.h>
  30. #include <strings.h>
  31.  
  32. #define OK 0
  33. #define NOTOK 1
  34. #define MAX_USERNAME 10
  35.  
  36. /*
  37.  * Given a Kerberos principal "kdata", and a local username "luser",
  38.  * determine whether user is authorized to login according to the
  39.  * authorization file ("~luser/.klogin" by default).  Returns OK
  40.  * if authorized, NOTOK if not authorized.
  41.  *
  42.  * If there is no account for "luser" on the local machine, returns
  43.  * NOTOK.  If there is no authorization file, and the given Kerberos
  44.  * name "kdata" translates to the same name as "luser" (using
  45.  * krb_kntoln()), returns OK.  Otherwise, if the authorization file
  46.  * can't be accessed, returns NOTOK.  Otherwise, the file is read for
  47.  * a matching principal name, instance, and realm.  If one is found,
  48.  * returns OK, if none is found, returns NOTOK.
  49.  *
  50.  * The file entries are in the format:
  51.  *
  52.  *    name.instance@realm
  53.  *
  54.  * one entry per line.
  55.  *
  56.  * The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin
  57.  * file entries.  See the file "kparse.c".
  58.  */
  59.  
  60. #ifdef ATHENA_COMPAT
  61.  
  62. #include <kparse.h>
  63.  
  64. /*
  65.  * The parmtable defines the keywords we will recognize with their
  66.  * default values, and keeps a pointer to the found value.  The found
  67.  * value should be filled in with strsave(), since FreeParameterSet()
  68.  * will release memory for all non-NULL found strings. 
  69.  *
  70. *** NOTE WELL! *** 
  71.  *
  72.  * The table below is very nice, but we cannot hard-code a default for the
  73.  * realm: we have to get the realm via krb_get_lrealm().  Even though the
  74.  * default shows as "from krb_get_lrealm, below", it gets changed in
  75.  * kuserok to whatever krb_get_lrealm() tells us.  That code assumes that
  76.  * the realm will be the entry number in the table below, so if you
  77.  * change the order of the entries below, you have to change the
  78.  * #definition of REALM_SCRIPT to reflect it. 
  79.  */
  80. #define REALM_SUBSCRIPT 1
  81. parmtable kparm[] = {
  82.  
  83. /* keyword    default             found value     */
  84. {"user",    "",                 (char *) NULL},
  85. {"realm",    "see krb_get_lrealm, below",    (char *) NULL},
  86. {"instance",     "",                (char *) NULL},
  87. };
  88. #define KPARMS kparm,PARMCOUNT(kparm)
  89. #endif ATHENA_COMPAT
  90.  
  91. kuserok(kdata, luser)
  92.     AUTH_DAT *kdata;
  93.     char   *luser;
  94. {
  95.     struct stat sbuf;
  96.     struct passwd *pwd;
  97.     char pbuf[MAXPATHLEN];
  98.     int isok = NOTOK, rc;
  99.     FILE *fp;
  100.     char kuser[MAX_USERNAME];
  101.     char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
  102.     char linebuf[BUFSIZ];
  103.     char *newline;
  104.     int gobble;
  105. #ifdef ATHENA_COMPAT
  106.     char local_realm[REALM_SZ];
  107. #endif ATHENA_COMPAT
  108.  
  109.     /* no account => no access */
  110.     if ((pwd = getpwnam(luser)) == NULL) {
  111.     return(NOTOK);
  112.     }
  113.     (void) strcpy(pbuf, pwd->pw_dir);
  114.     (void) strcat(pbuf, "/.klogin");
  115.  
  116.     if (access(pbuf, F_OK)) {     /* not accessible */
  117.     /*
  118.      * if he's trying to log in as himself, and there is no .klogin file,
  119.      * let him.  To find out, call
  120.      * krb_kntoln to convert the triple in kdata to a name which we can
  121.      * string compare. 
  122.      */
  123.     if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) {
  124.         return(OK);
  125.     }
  126.     }
  127.     /* open ~/.klogin */
  128.     if ((fp = fopen(pbuf, "r")) == NULL) {
  129.     return(NOTOK);
  130.     }
  131.     /*
  132.      * security:  if the user does not own his own .klogin file,
  133.      * do not grant access
  134.      */
  135.     if (fstat(fileno(fp), &sbuf)) {
  136.     fclose(fp);
  137.     return(NOTOK);
  138.     }
  139.     if (sbuf.st_uid != pwd->pw_uid) {
  140.     fclose(fp);
  141.     return(NOTOK);
  142.     }
  143.  
  144. #ifdef ATHENA_COMPAT
  145.     /* Accept old-style .klogin files */
  146.  
  147.     /*
  148.      * change the default realm from the hard-coded value to the
  149.      * accepted realm that Kerberos specifies. 
  150.      */
  151.     rc = krb_get_lrealm(local_realm, 1);
  152.     if (rc == KSUCCESS)
  153.     kparm[REALM_SUBSCRIPT].defvalue = local_realm;
  154.     else
  155.     return (rc);
  156.  
  157.     /* check each line */
  158.     while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) {
  159.     switch (rc) {
  160.     case PS_BAD_KEYWORD:
  161.     case PS_SYNTAX:
  162.         while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n'));
  163.         break;
  164.  
  165.     case PS_OKAY:
  166.         isok = (ParmCompare(KPARMS, "user", kdata->pname) ||
  167.             ParmCompare(KPARMS, "instance", kdata->pinst) ||
  168.             ParmCompare(KPARMS, "realm", kdata->prealm));
  169.         break;
  170.  
  171.     default:
  172.         break;
  173.     }
  174.     FreeParameterSet(kparm, PARMCOUNT(kparm));
  175.     }
  176.     /* reset the stream for parsing new-style names, if necessary */
  177.     rewind(fp);
  178. #endif ATHENA_COMPAT
  179.  
  180.     /* check each line */
  181.     while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
  182.     /* null-terminate the input string */
  183.     linebuf[BUFSIZ-1] = '\0';
  184.     newline = NULL;
  185.     /* nuke the newline if it exists */
  186.     if (newline = index(linebuf, '\n'))
  187.         *newline = '\0';
  188.     rc = kname_parse(principal, inst, realm, linebuf);
  189.     if (rc == KSUCCESS) {
  190.         isok = (strncmp(kdata->pname, principal, ANAME_SZ) ||
  191.             strncmp(kdata->pinst, inst, INST_SZ) ||
  192.             strncmp(kdata->prealm, realm, REALM_SZ));
  193.     }
  194.     /* clean up the rest of the line if necessary */
  195.     if (!newline)
  196.         while (((gobble = getc(fp)) != EOF) && gobble != '\n');
  197.     }
  198.     fclose(fp);
  199.     return(isok);
  200. }
  201.  
  202. #else
  203. static dummy;
  204. #endif